#ifndef SERVICE_SERVICE_H_
#define SERVICE_SERVICE_H_

#include <fermat/event/event_loop.h>
#include <fermat/event/channel.h>
#include <fermat/common/logging.h>
#include <fermat/common/timestamp.h>
#include <fermat/parser/properties.h>
#include <fermat/common/cmdline.h>
#include <fermat/log/fmtlog.h>
#include <signal.h>
#include <sys/signalfd.h>
#include <memory>
#include <functional>
#include <string>

using fermat::parser::Properties;
using fermat::event::EventLoop;
using fermat::event::Channel;
using fermat::Timestamp;
using fermat::File;
namespace fermat {
namespace event {

class EventLoop;

}
namespace service {

class Service;
typedef std::function<void(int sig, Service*)> SigCallBack;    
class Service{
    public:
       Service();
       virtual ~Service();
       void addSignal(int sig);
       virtual void setParseOption();
       int main(int argc, char*argv[]);

       bool  isDaemon();
    protected:
        void start();
        void stop();
        virtual void runDaemon();
        std::shared_ptr<Properties> loadConf(std::string& confpath);
        void                        setConf(std::shared_ptr<Properties> &conf);
        void                        resetLogger();
        bool                        testConf(std::shared_ptr<Properties> &conf);
        void                        configStop();
        void                        configReload();
        void                        reload();
		std::string                _logbase;
        std::string                _logName;
        std::string                _logPrefix;
        std::string                _logExtent;
		int                        _rollsize;
		int                        _interval;
		fermat::log::level_enum    _loglevel;
        int                        _reconf_count;

        
   protected:
		virtual int run() = 0;
		virtual void dispose() = 0; 
		virtual bool userSignalOpt(int sig);
		virtual std::string version();
        virtual bool appReConf(std::shared_ptr<Properties> &);
        virtual bool appTestConf(std::shared_ptr<Properties> &);

		void onReadSignal(Timestamp t);
		void defaultSignalOpt(int sig);
       
    protected:
        bool                            _isdaemon;
        bool                            _active; 
        int                             _signalfd;
        std::string                     _workdir;
        std::shared_ptr<Properties>     _conf;

        std::string                     _confFile;
        std::string                     _pidFile;

        std::unique_ptr<Channel>        _sigChannel;
        EventLoop                      *_loop;
        
        sigset_t                        _sigmask;
        CmdParser                          _args;
      

};

}

}
#endif
